#!/usr/bin/env ruby
# -*- coding: utf-8 -*-

# LanguageDetector : Language detection
# (c)2010 Nakatani Shuyo / Cybozu Labs, Inc.

require 'json'

module LanguageDetector
  LANGLIST = [
    # 日本語,中国語(繁体字),中国語(簡体字),韓国語,英語,フランス語,
    "ja", "zh-CN", "zh-TW", "ko", "en", "fr",
    # イタリア語,スペイン語,ロシア語,アラビア語,ベトナム語,タイ語,
    "it", "es", "ru", "ar", "vi", "th",
    # ドイツ語,ヒンディー語,ポルトガル語,インドネシア語,
    "de", "hi", "pt-PT", "id", 
    "nl", # オランダ語
    "sv", # スウェーデン語
    "pl", # ポーランド語
    "hu", # ハンガリー語
    "el", # ギリシャ語
    "uk", # ウクライナ語
    "iw", # ヘブライ語

    # "da", # デンマーク語 (以下、Google News なし)
    # "fi", # フィンランド語
    # "bn" # ベンガル語
    # "fa" # ペルシャ語
  ]

  CJK_CLASS = <<CLASS
万与乱争会体侠党内写凄刹剥励区医却厘厨参双叙叶号嘱国堕壮声奥学宝寝寿将尽届属屡峡庄弥当径怜恋恒悦惧惨担挟据携数断旧昼晋机条来枢栖椿楼横欧残殴没浅涛淀温湾湿滞潜灯炉点状独狭猪猫献画盗着碍礼祷称税窃粘胆脚脱芦苫茎莱葱蒋虚蚕蛮蝉装触誉践踊踪躯辞遥随静麦黄
両丼乗亀亘亜仏仮伎伝佼価侭俣俵値倶倹偲働兎児円冨冴処凧凪剣剤剰労効勅勧勲匁匂単厩厳収叡呉呑呪咲唄唖啓喩喰営嘘噂噌噛噺嚢団囲図圏圧坂埜埴埼堀堺塀塁塙塡塩増壊壌壱売壷変奨妬姉姫姶娯嬢嬬宍宕実寛対専尭尻岨岬峠峯嶋巌巣巻帯帰庁広廃廻廼弐弾彦従徳徴応恵悩悪惣懐戦戯戸戻払扱抜択拝拠拡拶挙挿捗捜掲掴掻揃揺摂撃撹斉斌斎晩暁暦曽杢枠柁柊柘査柾栂栃栄栢栴桜桝桟桧梶梼椀椋椙椛検椴楕楢楯楳楽榊榎様槙槻樋樗権樫橿檎櫨欝歓歩歯歳歴殻毎毘気氷汚沓沢浄浜涙涜渇済渉渋渓満溌滝漉潅瀞瀦瀧瀬焔焼犠狛猟獣珂瑠瑳甑産町畑畠畳畷疎痩発皐県矧砕砦砺砿硲碁碇碕祢禄禅禰稗稲穂穏穐穣窓竃竜竪笈笥笹筈箆箪篭籾粁粂粋粍粛粧糎紘紬紺経絵絶継続緋総緑縁縄縦繊繋繍繰罫翫聡聴脇脳臓舎舗舘艶苅茜荘菓菖萩葎葺蒔蔀蔦蔵蕎蕗薗薙薫薬薮藁蛍蛎蛸蝋蝿衆衿袴袷裏裾覇覗覚覧観訳詑説読諌諏謡譲讃讐豊貰賎賛贋転軽辺辻込辿迩逓遅遡郷酎酔酢醍醐醗醤醸釈鈎鉄鉢鉦鉱鉾銃銚銭鋭鋲鋳錆錬録鎌鎧鐙鑓関閲闇闘陥険隈隠隣隷隼雑雫雰霊靭鞄韮頚頬頴頼顔顕駄駅駆駈騒験騨髄髪鮎鮒鯵鰐鰯鰹鱈鱒鴇鴎鴫鴬鵜鶏鷲鹸麹麺麿黒黙齢
丞並亙亨仕伽佐併侃侶係俳俸倉個倖倣倫倭偉側偵偽傑傘備傭債傷傾僅僑僕儀億償優儲兇冊冥凋凍凱刈別則剛剝創劃劇劉劾動務勝勢匝匡協卯厄厭叢叩叱吋吾呂咋哉員問喋喚喪喫喬嗣嘆嘗嘩噴噸嚇園圭垣執堅報場塊塗塚塵塾墜墳墾壇壬夙夢奪奮妃妊妾姦姪娠娼婁婦媛嬰孜孫宥宮寅寧審寮寵尋導屍層岐岡岱峨島嵐嵩嵯嶺巳巽帥師帳幡幣幹幾庖庚庫廟廠廿弁弔弗弘張強弼彊彙彫後復徹恣恥悌悶惇惚惟愛慄態慣慮慶慾憂憐憤憧憩憬憲憶懇懲懸戊戎戟扉捨捲掃掛採掬揚換揮損搾摯摺撚撫撲擁擢擬擾敗敵斐斡斬於昇時暢暫曇曖曜曝曳書朔朕札杓東杵杷枇柚柵桁桓桔梓梱棄棟棲楊楓楠業極構槌槍標樵樹樺樽橋機櫓櫛欄欽歎殆殺毀氾汀汎汐汝汲決沌沖況洩浬涼淵渚減渥渦測湊湛湧湯準溝滅漁漕漢漣漬漸潔潟潤潰澗澱濁濃濠濡濫濯瀕灘災為烏無煉煙煩煽熱燈燐燦燭爺爾牒牝牟牽狙狩狽猶猷獄獅獲珪現琵琶瑚瑛環璽畝畢異畿疋痔瘍療癒癖盃監盤眺瞥矯砥砧砲硯碓碩確磐磯礎祁祇祉祐禍禎禦禿稔稜種穀積穎穫窪窮窯窺競竺笠筆箇箋箔箸節範築篠篤簡簾籠粕糞糧糸糾紀約紅紋納紐純紗紙級紛紡細紳紹終絃組結絞絡絢給統絹綜綬維綱網綴綻綾綿緊緒線締編緩緬緯練緻縛縞縫縮績織繕繭纂纏缶罰罵罷羅羨義翌習耶聖聞聯職聾肇肱胤胴脅脈脹腎腫腸膚膿臆臥臨興舛舜艦艮芸苑苓苧茨荊荏荻莞菅菟華菰萱葉葦蒐蒼蓋蓑蓮蔭蕃蕨蕩蕪薦薩藍藩藷蘇蘭虜虞虻蛭蝕蝦蟻術衛衝袈補裟裡製複襖襲見規視親訂訃計訊討訓託記訟訣訪設許訴診註証詐詔評詞詠詣試詩詫詮詰話該詳誇誌認誕誘語誠誤誰課誹誼調談請諒論諜諦諧諭諮諸諺諾謀謁謂謄謎謙講謝謬謹識譜議護豚貝貞負財貢貧貨販貪貫責貯貴買貸費貼貿賀賂賃賄資賊賑賓賜賞賠賢賦質賭購贈趨跡蹟蹴躍車軌軍軒軟軸較載輔輝輩輪輯輸輿轄轍轟轡農迦迭這連週進遁遊運過達違遜遠適遷選遺遼還邸郡郵鄭酉酋醜釆釘釜針釣釦釧鈍鈴鈷鉛銀銅銑銘鋒鋤鋪鋸鋼錐錘錠錦錨錫錮錯鍋鍍鍔鍛鍬鍵鍾鎖鎗鎚鎮鏑鏡鐘鐸鑑長門閃閉開閏閑間閣閤閥阜阪陀陛陣陰陳陸陽隊階際隻雛離難雲電霧鞘韓韻響頁頂頃項順須預頑頒頓頗領頭頰頻題額顎願顛類顧風飛飢飯飲飴飼飽飾餅養餌餓館饗馨馬馳馴駁駐駒駕駿騎騰驚骸髭鬱魅魚魯鮪鮫鮭鮮鯉鯖鯛鯨鰍鰭鰻鱗鳥鳩鳳鳴鳶鴛鴨鴻鵠鵡鵬鶴鷹鷺麓麗麟黛龍
丐丰么乒乓乖乘于仆仍仗份仿伙估佛你佣佩侈俏俐俘俯俱倔倘倚倡值假偎做偷傀傅傻僵儡儿兔兢冀冕冤冰几凰凳刁划刨刮剔剩剪剿劈勒匆匈匕匣匾卡卷另叨叭叮叼吁吆吝吞吧吩听吭吮吱吵吼呀呢呵呻咆咐咒咕咖咧咨咪咬咱咸哄哈哎哥哪哭哮哼唁唉唧唬售啃啊啡啤啦啼喂喇喊喘喳喻嗓嗜嗡嗤嗦嗽嘀嘴嘶嘹嘿噩噪嚎嚷嚼囊囤圈圾址坎坏坡坷垃垮埂埃堡塌墅增墩壤壹夭夸奕奠奢奶奸她妒姆姊姚姜姨娜娶婉媚媳嫂嫩孕孩孵孽它宦寇寞寥寨尸屁屎屏屹岔峭崔嵌巍巢巫已帕帘帚幔幢并彤彭很徊徘徙德忱忿怎怔怕恃恍恤恬悄悍您悴惋惕惠惦惶愕愧愿慷憔懂懈懊懦戈截戳扁扎扑扒扔扛扣扭扯扳扼找抒抓抖抬拂拄拆拇拌拔拖拗拜拯拱拴拼拿挂挖挪捂捆捍捎捏捐捶掀掉掏掖揉揍插揣揩揪揭搏搓搔搜搞搪摔摧摹撇撕撩撬撼擂擅擎擒攀攘收效敞敲斟旁旱晌晚晤晨晰晾曼朦朵杆杠杰枉柒查柬桅框桌梆梭梳棍棕棘棠棵椒椰楔楞楣榆榕榜榨榴槐樊橄橙檐檬歇歉步歧歹殃殷每毫毯氓氛氧氨氮氯汛汞污汪沉沐沛沮沽沾泄泛泵洽浙涉涎涕涮涵淆淌淤淮淹渣渤渴游渺湃溉溪溯滓滔漓漩漱漾潘潦潭澈澎澡澳瀑灌灶炒炕炫炬炮炸烘烙烤焊焙焰煌煞熄熙熬燎爬爸爹犁狠狡猖猜猩猴猾玫玷玻琅瑟瑰瓣瓤瓷甩甸畸疆疙疚疤疼痊痰瘟瘤瘦瘩瘸皂盅盒盔盯盹盼眨眶眷睛睬睹瞄瞎瞧瞪瞻矗矮砌砍砰砸硼碉碌碎碘碟碰碳碾磅磕磷祟祠秉秧稍稠稻穗窖窗窘窿站竟竭笆笙笨筐筷篙篡篷簇籽粱粹糕糙糜糯紊絮缸缺罐罕罩羔羹翅翎翔翩耍耘耙耿聊聘聚肄肆肚肛胖胚胯胰胳脖脯脾腋腌腥腮膀膊膘膛臀臂舀舅舍舒舔艘艾芍芒芬苞苟茁范茉茫茴茵荐荔荸莉莽菠菲萍葫蒂蒿蔗蔬蕾薇薛藏藐藕蘑蘸虱蚌蚓蚜蚣蚪蚯蛀蛆蛉蛔蛛蛹蜀蜈蜓蜻蝌蝗蝙蝠蝴螃螟蟀蟆蟋蠕蠢衍衙衫袁袍袒袱裙裹褂褥褪譬豁豌豫豺趁趟趴趾跋跌跑跛跟跪跺踢踩踱蹂蹈蹋蹦蹬蹲躁躬躲躺辜辟辨逛逞逾遏邀邢鄙酗酣酥醉醋阱陋陌陡陷隘隧雕雹霉霍霎霸霹靠靡靶鞋韭髓魄魏黎黑黔默
专业丛东丝丢两严丧个临为丽举义乌乐乔习乡书买亏亚产亩亲亿仅从仑仓仪们价众优伞伟传伤伦伪侄侣侥侦侧侨俩俭债倾偿储兑兰关兴养兽冈册军农冯冲决况冻净凉减凑凛凤凫凭凯击凿刘则刚创删别刽剂剑剧劝办务动劲劳势勋匀华协单卖卢卤卧卫厂厅历厉压厌厕厢厦县叁发变叠叹叽吓吕吗吨启吴呐呕员呛呜咏咙哆响哑哗哟唠唤啥啰啸喷嘁嚣团园囱围图圆圣场块坚坛坝坞坟坠坯垄垒垛垦垫墙壳壶处备复够夯头夹夺奋奖妆妇妈娄娇娱婴婶孙宁实宠审宪宫宽宾对寻导尔尘尝层屉屿岁岂岖岗岛岭峦崭巩币帅师帐帜带帮广庆庐库应庙庞废开异弃张弯弹强归录彻忆忧怀态总恳恶恼悬悯惊惩惫惭惯愤憋憨懒戏战户执扩扫扬扰抚抛抠抡抢护报拟拢拣拥拦拧拨择挎挚挠挡挣挤挥捅捞损捡换捣掂掐掰掷掸掺揽搀搁搂搅摄摆摇摊撑撵攒敌敛斋斩无时旷昙昵显晓晕暂术杀杂权杈杨极构枣枪枫枷柜柠栅标栈栋栏树样档桥桦桨桩梦检棱椭榄樱橱檩欢歼毁毕毙毡气氢汇汉汤汹沟沥沦沧沪泞泪泻泼泽洁洒洼浆浇浊测济浑浓涂涝涡涣涤润涧涨涩渊渐渔渗溃溅滚满滤滥滨滩澜濒灭灵灾灿炼烁烂烛烟烦烧烫热焕熏爱爷牍牵牺犹狈狞狮狰狱猎猬玛环现琐琼瓮电畅畴疗疟疮疯痒痪痹瘪瘫瘾癞癣皱盏盐监盖盘眯睁瞒矫矾矿码砖砚砾础硅硕确碱碴祸禀离秃秆种秕秫积秸秽稳穷窍窑窜窝窥竖竞笋笔笤笼筛筝筹签简箍箩箫篓篮篱类粤粪粮紧纠红纤约级纪纫纬纯纱纲纳纵纷纸纹纺纽线练组绅细织终绊绍绎经绑绒结绕绘给络绝绞统绢绣继绩绪续绰绳维绵绷绸综绽绿缀缅缆缎缓缔缕编缘缚缝缠缤缨缩缭缰缴网罗罚罢羡翘耸耻聂聋职联聪肃肠肤肮肾肿胀胁胜胧胶脉脏脐脑脓脸腊腻腾臊舆舰舱艰艳艺节芜苇苍苏苹茧茬荆荚荞荠荡荣荤荧药莲获莹莺菇萝萤营萧萨蓖蓝蔫蔼蕴虏虑虽虾蚀蚁蚂蜒蜕蜗蜡蝇蝎蟥衅衔补衩衬袄袜袭裆裤见观规觅视览觉誊计订认讥讨让训议讯记讲讳讶许讹论讼讽设访诀证评诅识诈诉诊词译试诗诚话诞诡询该详诫诬语误诱诲说诵请诸诺读诽课谁调谅谆谈谊谋谍谎谐谒谓谚谜谢谣谤谦谨谬谭谱谴贝贞负贡财责贤败账货质贩贪贫贬购贮贯贰贱贴贵贷贸费贺贼贾贿赁赂赃资赊赋赌赎赏赐赔赖赘赚赛赞赠赡赢赵赶趋跃跷蹭躏车轧轨轩转轮软轰轴轻载轿较辅辆辈辉辐辑输辕辖辙辩辫边辽达迁过迈运还这进远违连迟迹适选逊递逻遗邓邮邻郑酝酱酿释鉴针钉钓钙钝钞钟钠钢钥钦钧钩钮钱钳钻钾铁铃铅铆铐铛铜铝铡铣铭铲银铸铺链销锁锄锅锈锉锋锌锐错锚锡锣锤锥锦锨锭键锯锰锹锻镀镇镊镐镜镣镰镶长门闪闭问闯闰闲间闷闸闹闺闻闽阀阁阅阎阐阔队阳阴阵阶际陆陈陕陨险隐隶难雏雳雾韧韩韵页顶顷项顺须顽顾顿颁颂预颅领颇颈颊频颓颖颗题颜额颠颤风飒飘飞饥饭饮饰饱饲饵饶饺饼饿馁馅馆馋馍馏馒马驮驯驰驱驳驴驶驹驻驼驾骂骄骆骇验骏骑骗骚骡骤鬓鱼鲁鲜鲤鲫鲸鳄鳍鳖鳞鸟鸠鸡鸣鸥鸦鸭鸯鸳鸵鸽鸿鹃鹅鹉鹊鹏鹤鹦鹰麸齐齿龄龙龟
一丁七丈三上下不丑且世丘丙中串丸丹主乃久之乍乎乏乙九乞也乳乾了予事二云互五井些亡交亥亦享京亭亮人什仁仇今介仔他付仙代令以仰仲件任企伊伍伏伐休伯伴伶伸伺似佃但位低住佑何余作佳使例侍供依侮侯侵便促俄俊俗保信修俺倍倒候借倦偏停健偶傍催傲像僚僧僻儒允元兄充兆先光克免兜入全八公六共兵其具典兼再冒冗冠冬冶冷准凌凝凡凶凸凹出函刀刃分切刊刑列初判利到制刷券刺刻剃削前剖副割力功加劣助努劫勃勇勉勘募勤勺勾勿包化北匙匠匪匹匿十千升午半卑卒卓南博卜占卦印危即卵卸卿厚原去又叉及友反叔取受叛口古句只叫召可台史右司吃各合吉吊同名后吏吐向君吟吠否含吸吹吻呆呈告周味呼命和咳咽哀品哨哩哲哺唆唇唐唯唱唾啄商善喉喜喝喧嗅嘉嘲器囚四回因困固圃土在地均坊坐坑坤坦坪垂型垢埋城域埠培基堂堆堤堪堰堵塑塔塘塞填境墓墨壁壕士夏夕外多夜大天太夫央失夷奄奇奈奉奏契奔套女奴好如妄妓妖妙妥妨妹妻始姐姑姓委姥姻姿威娃娘娩婆婚婿媒嫁嫉嫌嫡嬉子孔字存孝孟季孤宅宇守安宋完宏宗官宙定宛宜客宣室宰害宴宵家容宿寂寄密富寒寓察寡寸寺封射尉尊小少尖尚尤就尺尼尾尿局居屈屋屑展屠履屯山岩岳岸峰峻崇崎崖崩川州巡工左巧巨差己巴巷巾市布帆希帖帝席常帽幅幌幕干平年幸幻幼幽庇床序底店府度座庭庵庶康庸廉廊廓延廷建弄弊式弓引弛弟弦弧弱形彩彪彬彰影役彼往征待律徐徒得御循微徽心必忌忍志忘忙忠快念忽怒怖思怠急性怨怪怯恐恕恢恨恩恭息恰悉悔悟悠患悲悼情惑惜惰想惹愁愈愉意愚感慈慌慎慕慢慧慨慰憎憾成我戒或戚戴房所扇手才打托扮扶批承技抄把抑投抗折披抱抵抹押抽拉拍拐拒拓拘拙招括拭拳拷拾持指按挑挨挫振挺挽捉捌捕捧捷捺捻授掌排掘掠探接控推掩措描提揖握援搬搭摘摩摸撒撞撤播撮撰操擦支改攻放政故敏救教敢散敦敬整敷文斑斗料斜斤斥斧斯新方施旅旋族旗既日旦旨早旬旭旺昂昆昌明昏易昔星映春昧昨昭是晃晒晦普景晴晶智暇暑暖暗暮暴曙曲更曹曾替最月有朋服朗望朝期木未末本朱朴朽杉李杏材村杖杜束杭杯松板析枕林枚果枝枯架柄柏某柑染柔柱柳柴柿栓栗校株核根格栽桂桃案桐桑桶梁梅梗梢梧梨梯械棉棋棒棚森棺椅植椎楚楷概榔榛槽樟模橘橡檀欠次欣欲欺款歌止正此武歪死殉殊殖段殿毅母毒比毛氏民水永汁求汗江池汰汽沃沈沙沫河沸油治沼沿泉泊泌法泡波泣泥注泰泳洋洗洛洞津洪洲活派流浦浩浪浮浴海浸消涌涯液淋淑淘淡淫深淳混添清渠渡港湖湘源溜溢溶溺滋滑滴漂漆漏演漠漫潮澄激火灰灸灼炊炎炭烈烹焚焦然煎煤照煮熊熔熟燃燕燥爆爪爵父爽片版牌牙牛牡牢牧物牲特犀犬犯狂狐狗狸狼猛猿玄率玉王玖玩玲珊珍珠班球理琉琢琳琴瑞璃璧瓜瓢瓦瓶甘甚甜生甥用甫田由甲申男界畏畔留畜略畦番疏疑疫疲疹疾病症痕痘痛痢痴癌登白百的皆皇皮皿盆盈益盛盟目盲直相盾省眉看真眠眼睡督睦瞬瞭瞳矛矢知矩短石砂研破硝硫硬碑碗碧磁磨礁示社祈祖祝神祥票祭禁福禽禾秀私秋科秒秘租秤秦秩移稀程稚稼稽稿穆穴究空穿突窄窒窟立章竣童端竹竿笑笛符第等筋筏筑筒答策箕算管箭箱篇簸簿籍米粉粒粗粟粥精糊糖糟糠系素索紫累繁罪置署羊美羞群羽翁翠翰翻翼耀老考者而耐耕耗耳耽肉肋肌肖肘肝股肢肥肩肪肯育肴肺胃背胎胞胡胸能脂脆脊腐腔腕腰腹腺腿膏膜膝膨膳臣自臭至致臼舌舞舟航般舵舶舷船艇良色芋芙芝芥芭芯花芳芹芽苔苗苛若苦英茂茄茅茶茸草荒荷莫菊菌菜菩菱萄萌萎落著葛葡董葬葵蒙蒜蒲蒸蓄蓉蓬蔑蔓蔚蔽蕉蕊薄薪薯藤藻虎虐虫虹蚊蚤蛇蛋蛙蛤蛾蜂蜘蜜蝶融螺蟹血行街衡衣表衰衷袋袖被裁裂裕裳裸褐褒襟西要覆角解言誓警谷豆象豪豹貌赤赦赫走赴起超越趣足距跨路跳踏蹄身辛辣辰辱迂迄迅迎近返迫述迷追退送逃逆透逐途逗通逝速造逢逮逸逼遂遇遍道遣遭遮遵避邑那邦邪郁郊郎部郭都酌配酒酪酬酵酷酸醇醒采里重野量金防阻阿附降限院除陪陵陶隅隆隔隙障雀雁雄雅集雇雌雨雪零雷需震霜霞露青靖非面革靴鞍鞠鞭音食餐首香骨高鬼魁魂魔鹿麻黍鼎鼓鼠鼻
丕丟丫乩亂亞亟亢亳仃仄仞仟仳伉伋伕佇佈佔佗佚佝佞佬佯佰佺佻佾來侏侑侖侷俎俑俚俞俟俠俾倀倆倌倏們倥倨倩倪偃偌偕偭偯偺傖傚傢傯傳僇僎僖僥僩僭僮僱價儂儅儈儉儐儔儕儘儳儷儸儻儼兀兌兒兕兗內兩兮冉冑冢冪冽凜刎刖刪剁剋剌剎剜剴剷剽劂劊劍劑劓劬劻勁勗勛勞勣勦勰勳勵勸勻匍匏匐匯匱區卅卉卞卮卹卻厝厥厲參叟叵叻吒吳吶呃呎呱呶呷呸咀咄咎咚咦咩咫咯咻咿哂哇哦哽唏唔唳唷唸啁啕啖啗啜啞啟啣啪啻啾喀喃喔喙喟單喱喲嗆嗇嗉嗎嗑嗚嗟嗥嗨嗯嗶嗷嗾嘈嘍嘎嘐嘔嘖嘛嘟嘮嘯嘰嘻噎噓噗噙噢噤噥噫噬噯噱噶噹嚀嚅嚏嚐嚕嚥嚨嚮嚴嚶囀囁囂囈囉囌囑囝囪囫囿圄圉國圍圓圖團圩圬圯圳圻坍坩坼垓垠埔埤堉堊堝堠堯塋塒塢塭塹塽墀墊墟墦墮壅壎壑壓壘壙壞壟壢壩壯壺壽夔夠夤夥夾奎奐奘奚奧奩奭妁妍妝妞妣妤妮妯妳姅姍姒姘姣姬娉娌娑娓娛娟娣娥婀婊婢婪婷媧媲媼媽媾嫖嫗嫘嫣嫦嫵嫻嬈嬋嬌嬝嬤嬪嬴嬸孀孃孑孓孚孛孰孱孳學孺孿宸寐寢寤實寫寬寰寶將專對尢尬尷尹屆屐屘屜屝屢屨屬岌岑岫岷峒峙峪峴峽崁崆崑崗崙崛崢崤崧崴嵇嶄嶇嶔嶝嶸嶼嶽巉巒巔巖帑帛帟帶帷幀幃幗幛幟幫庠庾廁廂廄廈廖廚廝廢廣廬廳廾弈弋弒弩弭彆彈彌彎彗彝彥彷彿徇徉徑徜從徠徨徬徵忖忝忪忸怏怛怡怩怫怵恆恙恪恫恿悅悖悚悵悸悻悽惆惘惡惱惴惺惻愀愆愍愎愒愜愣愴愷愾慇慍慘慚慝慟慫慵慼憊憑憚憫憮應懋懍懣懵懶懷懺懼懾懿戀戌戍戕戛戡戢戮戰戲戶戾扈抆抉抨抿拈拋拎拚拮拽挈挾捩捫捱掄掙掣揀揆揹搆搖搗搴搶搽摑摒摟摭摻撈撐撓撙撢撥撳撻撾撿擄擇擊擋擔擘據擠擭擰擱擲擴擷擺擻攆攏攔攙攜攝攣攤攪攫攬攸敉敔敕敖敘敝數斂斃斕斛斫斷旌旎旖昀昊昕昤昱晁晅晉晏晝晞晷暄暈暉暍暘暝暨暱暸暹曄曆曉曠曦曩曬曰曷會朧朮杗杞杪杲杳杼枋枓枰枴枸柙柝柞柢柩柯栘栩桀桿梂梃梔條梟梡梵棗棣棧棹棻楛楝楨楫楮楹榣榦榫榭榮榷榻槁槃槓槨槭槳樁樂樅樑樓樞樣樸橇橈橢橫橾檄檔檗檜檠檢檣檮檯檳檸檻櫂櫃櫚櫝櫥櫬櫺櫻權欐欖歐歙歜歟歡歲歷歸歿殘殤殮殯殲殼毆毋毓毗毚毬毽氅氈氐氖氟氣氤氦氫氬氳汍汕汙汨汴汶汾沁沂沅沆沍沒沔沘沬沱泅泓泖泗泜泠泯泱洌洎洧洫洮洱洵洶洸洹浚浥浹涅涇涊涓涔涪涸涿淄淅淇淒淙淚淞淦淨淪淬淺渙渝渭渲渾湄湍湎湔湟湣湩湮湲溘溥溧溫溴溼滂滄滇滌滕滬滯滲滷滾滿漪漯漲漳漿潑潛潠潯潸潺潼澀澆澠澤澦澧澴澶澹濂濕濘濛濟濤濩濬濮濰濱濺濾瀆瀉瀋瀏瀘瀚瀛瀝瀟瀨瀰瀲瀾灑灞灣灤炙炤炯炳烊烯烽焉焜煆煖煜煥煦煨煬熒熨熹熾燄燉燒燙燜營燠燧燬燮燴燸燻燼燾爍爐爛爨爭爰爻牆牖牘牠牯牴犄犒犖犛犢犧狀狄狎狷狹猓猙猥獎獐獗獨獰獵獷獸獺獻玀玆玟玥玨玳珀珞珮琊琍琛琥琦琨琪琯琺琿瑁瑕瑙瑜瑣瑤瑩瑪瑭瑯瑾璀璋璘璜璞璟璣璦璨璩璿瓊瓏瓔瓖瓚瓠甄甌甍甕產甦甬甭甽畋畎畚畫當疇疊疝疢疣疥疳疵疸疽痂痍痙痞痠痣痱痲痳痺痿瘀瘁瘉瘋瘓瘠瘡瘢瘧瘴瘺癆癘癟癡癢癥癩癬癮癱癲癸發皈皋皎皓皖皚皰皴皺盂盍盎盜盞盡盥盧盪眇眩眸眾睏睜睞睢睥睨睪睫睽睿瞇瞋瞌瞑瞞瞟瞠瞰瞼瞽瞿矇矓矚矜矣矽砝砟砠砭砷硃硎硿碣碼磊磋磚磧磬磴磺礙礦礪礫礬祀祆祕祗祚祺祿禧禪禮禱禳禹禺秈秣稅稈稞稟稱稷穋穌穠穡穢穩穹窈窕窠窩竄竅竇竊竽笞笮筍筠筧筮筵箄箏箝箠箴篁篆篌篛篦篩篾簌簍簑簞簣簧簪簫簷簽籀籃籌籐籟籣籤籥籬籮籲粳粵粽糝糢糰紂紆紇紉紕紜紮紱紲紼絀絆絕絛絨絰絲絳綁綏綑經綞綠綢綰綵綸綺綽緇緘緙緝緞緣緲緹縈縉縊縐縑縝縣縯縱縲縴縵縷縹總縿繃繅繆繈繒繙繚繞繡繩繪繫繳繹繼繽續纓纔纖纜缽罄罈罌罔罟罹羈羋羌羚羯羲羶羸羼羿翕翟翡翮翱翳翹耄耆耋耑耒耜耦耨聆聒聰聱聲聳聶聽聿肅肓肫胄胛胝胥胭胱胼脣脤脩脫脰腆腑腓腦腱腳腴膂膈膠膩膺膽膾臃臉臍臏臘臚臟臢臧臬臺臻臾舂與舉舊舐舢舨舫艋艙艱艷芟芣芰芷芻芾苒苜苣苯茆茗茱茲茹荀荃荼莆莊莎莒莓莖莘莠莢莧菁菔菴菸菽萃萇萊萋萬萵萸萼葆葩葭葷蒞蓀蓆蓊蓓蓿蔆蔔蔡蔣蔥蕈蕙蕞蕭薊薑薔薜薨薰薹薺藉藝藥藪藹藺蘆蘊蘋蘗蘚蘿虔處虛號虧虺蚩蚱蚵蚶蛄蛐蛞蛟蛻蜃蜆蜇蜊蜢蜥蜩蜴蜷蜿蝓蝨蝸螂螞螢螫螳螻蟈蟑蟒蟠蟬蟯蟲蟾蠅蠍蠔蠟蠡蠣蠱蠶蠹蠻衢衹衽袂袞裊裒裔裘裝裨裯裴褊褓褕褚褡褫褲褶褸褻褽襄襞襠襤襪襬襯覃覓覜覦覬覲覺覽觀觔觴觸觼訌訏訐訑訕訖訛訝訢訥訶訾詁詆詖詛詢詨詬詭詹詻詼誅誑誚誡誣誥誦誧誨說誶諂諄諉諍諛諫諱諳諶諷諼謊謐謗謠謨謫譁譆證譎譏譙譚譟譫譯譴譽讀變讒讓讖讚讜谿豈豉豎豐豔豕豢豬豭豳貂貉貊貍貓貲貳貶貽賁賅賈賒賡賣賤賬賴賸賺賻賽贅贊贍贏贓贖贗贛赧赭赳趕趙趺跆跎跚跤跦跼踐踝踞踟踡踫踴踵踹蹉蹊蹕蹙蹣蹤蹶蹺蹼躂躅躇躉躊躋躑躓躡躪軀軋軏軔軛軻軼軾輊輒輓輕輛輜輞輟輥輦輳輻輾轂轅轉轎轔辦辭辮辯迆迢迤迥迨迪迴迸迺逅逍逕逖逵逶遐遑遘遙遛遝遞遢遨遲遴遽邁邂邃邇邈邊邋邏邐邕邱邵邶郃郝郢郾鄂鄉鄒鄗鄘鄞鄧鄰鄱鄴鄹酈酊酩酴醃醞醣醫醬醮醱醴醺釀釁釅釉釋釐釗釙釩釭釵鈇鈉鈐鈑鈔鈕鈞鈣鈸鈹鈽鈾鈿鉀鉅鉉鉋鉍鉑鉗鉚鉤鉸鉻鉼銓銖銜銨銬銲銳銷銻銼鋁鋅鋇鋰錄錕錙錚錡錢錳錶鍊鍚鍥鍰鎂鎊鎔鎘鎢鎬鎰鎳鏃鏈鏍鏖鏗鏘鏜鏝鏟鏢鏤鏨鏽鐃鐫鐮鐲鐳鐵鐺鑄鑒鑠鑣鑤鑪鑰鑲鑷鑼鑽鑾鑿閂閎閒閔閘閡閨閩閭閱閻闆闈闊闋闌闐闔闕闖關闡闢阡阬阮陂陘陝陞陬陲陴隄隋隍隕隨險隱隴隸隹雉雊雋雍雒雖雙雜雞雩雯霄霆霏霑霓霖霤霪霰霽霾靂靄靈靛靜靦靨靼鞅鞏鞣鞦韁韃韆韉韋韌韜韶韹頊頌頜頡頤頫頷頸頹顆顏顓顥顫顯顰顱颯颱颳颶颺颼飄飧飩飪飭餃餉餒餘餚餛餞餡餮餵餽餾餿饅饉饑饒饕饜饞馥馭馮馱駑駙駛駝駟駢駭駱騁騖騙騫騵騷騾驀驃驅驍驕驗驛驟驢驥驪骯骰骷骼髁髏髑髒體髖髡髦髮髯髻鬃鬆鬍鬚鬢鬣鬥鬧鬨鬲魍魎魑魘魷鮑鯀鯈鯊鯧鯽鰓鰥鰱鰾鱉鱔鱖鱟鱷鱸鴃鴆鴉鴒鴕鴣鴦鴿鵑鵝鵪鵲鶉鶯鶸鷂鷓鷗鷥鸚鸛鸞鹵鹹鹼鹽麂麋麒麝麥麩麴麵麼麾黃黌黏黜黝點黠黨黯黴黷鼇鼕鼙鼬鼯鼴鼾齊齋齒齜齟齡齣齦齧齪齬齲齷龐龔龜
CLASS

  @cjk_class = Hash.new
  CJK_CLASS.each_line do |line|
    line.chomp!
    if line =~ /^./
      representative = $&
      line.scan(/./) do |char|
        @cjk_class[char] = representative
      end
    end
  end

  def self.normalize(x)
    if x.ord <= 64
      " "
    elsif @cjk_class.key?(x)
      @cjk_class[x]
    elsif x =~ /^[\u0e00-\u0e7f]/ # ฀-๿ /^\xe0[\xb8-\xb9][\x80-\xbf]/  # Thai
      ?\u0e11
    elsif x =~ /^[\u1ea0-\u1eff]/ # Ẁ-ỿ /^\xe1[\xba-\xbb][\x80-\xbf]/  # Latin Extended Additional(Vietnam)
      ?\u1ec3
    elsif x =~ /^[\u3041-\u30f6]/ # ぁ-ヶ /^\xe3[\x81-\x83][\x80-\xbf]/  # Hiragana / Katakana
      ?\u3042
    elsif x =~ /^[\uac00-\ud7a3]/ # 가-꿿 /^\xea[\xb0-\xbf][\x80-\xbf]/  # Hangul Syllables 1
                                  # 뀀-힣 /^[\xeb-\xed][\x80-\xbf]{2}/   # Hangul Syllables 2
      ?\uac00
    else
      x
    end
  end

  class Ngramer
    def initialize(n)
      @n = n
      clear
    end
    def clear
      @grams = [" "]
    end
    def append(x)
      clear if @grams[-1] == " "
      @grams << LanguageDetector::normalize(x)
      @grams = @grams[-@n..-1] if @grams.length > @n
    end
    def get(n)
      return nil if @grams.length < n
      @grams[-n..-1].join
    end
    def each
      (1..@n).each do |n|
        x = get(n)
        yield x if x && x != " "
      end
    end
  end

  class Detector
    def initialize(filename, alpha=1)
      @n_k, @p_ik, @n = open(filename){|f| JSON.load(f) }
      @p_ik.each do |lang, freq|
        freq.default = 0
      end
      @n ||= 3
      @alpha = alpha.to_f
      @debug = false
    end
    def debug_on; @debug = true; end
    def ngramer; Ngramer.new(@n); end
    def init(alpha=nil)
      @prob = Hash.new
      @n_k.keys.each {|lang| @prob[lang] = 1.0 }
      @maxprob = 0
      @alpha = alpha.to_f if alpha
    end
    def append(x)
      return unless @p_ik.key?(x)
      freq = @p_ik[x]
      puts "#{x}: #{freq.inspect}" if @debug
      sum = 0
      @n_k.each do |lang, n_k|
        @prob[lang] *= (freq[lang] + @alpha * freq.length) / (n_k + LANGLIST.length * (@alpha * freq.length))
        sum += @prob[lang]
      end
      @maxprob = 0
      @prob.keys.each do |lang|
        @prob[lang] /= sum
        @maxprob = @prob[lang] if @maxprob < @prob[lang]
      end
      p problist(0.1) if @debug
    end
    def detect(text, alpha=nil)
      alpha *= text.length / 100.0 if alpha && text.length < 100
      init alpha

      ngram = ngramer
      text.scan(/./) do |x|
        ngram.append x
        ngram.each do |z|
          append z
        end
        break if @maxprob > 0.99999
      end
      problist
    end
    def maxprob; @maxprob; end
    def problist(t=0.01); @prob.to_a.select{|x| x[1]>t}.sort_by{|x| -x[1]}; end
  end
end
